package com.liholin.springboot.sample.utils;


import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Base64;

/**
 * Created by Andon on 2017/8/3.
 */
public class FileToBinary {
    /**
     * 图片转二进制（基于64位）
     * @return
     */
    public static String getImageBinary(String url, String type){
        File file = new File(url);
        BufferedImage bufferedImage;
        try{
            bufferedImage = ImageIO.read(file);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, type, baos);
            byte[] bytes = baos.toByteArray();
            return Base64.getEncoder().encodeToString(bytes).trim();
        }catch (IOException e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将二进制转成图片(基于64位)
     * @param base64String
     */
    public static void base64StringToImage(String base64String, String pathName){
        try{
            byte[] bytes = Base64.getDecoder().decode(base64String);// decoder.decodeBuffer(base64String);
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
            BufferedImage bil = ImageIO.read(bais);
            File file = new File(pathName);
            ImageIO.write(bil, "jpg", file);
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    /**
     * @Description: 将base64编码字符串转换为图片
     * @Author:
     * @CreateTime:
     * @param fielStr base64编码字符串
     * @param path 图片路径-具体到文件
     * @return
     */
    public static boolean generateFile(String fielStr, String path) {
        if(fielStr == null)
            return false;
        BASE64Decoder decoder = new BASE64Decoder();
        try{
            byte[] bytes = decoder.decodeBuffer(fielStr);
            for(int i = 0; i <bytes.length; i ++){
                if(bytes[i] < 0){
                    bytes[i] += 256;
                }
            }
            OutputStream out = new FileOutputStream(path);
            out.write(bytes);
            out.flush();
            out.close();
            return true;
        }catch (Exception e) {
            return false;
        }
    }

    public static byte[] getImgeHexString(String URLName, String type){
        byte[] result = null;
        try{
            int httpResult = 0;
            FileInputStream fileInputStream = new FileInputStream(URLName);
            if(httpResult == HttpURLConnection.HTTP_OK)
                System.out.println("fail");
            else{
                BufferedInputStream bis = new BufferedInputStream(fileInputStream);
                BufferedImage bm = ImageIO.read(bis);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                ImageIO.write(bm, type, bos);
                bos.flush();
                byte[] data = bos.toByteArray();
                bos.close();
                result = addBytes(hex2byte("0x"), data);
            }
        }catch(IOException e){
            e.printStackTrace();
        }
        return result;
    }
    public static byte[] image2Bytes(String imgSrc){
        byte[] bytes = null;
        try {
            FileInputStream fin = new FileInputStream(new File(imgSrc));
            bytes  = new byte[fin.available()];
            fin.read(bytes);
            fin.close();
        }catch (Exception e){}

        return bytes;
    }

    /**
     * 格式化byte
     * @param bytes
     * @return
     */
    public static String byte2hex(byte[] bytes){
        char[] digit = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        char[] out = new char[bytes.length * 2];
        for (int i = 0; i < bytes.length; i ++){
            byte c = bytes[i];
            out[i * 2] = digit[(c >>> 4) & 0x0f];
            out[i * 2 + 1] = digit[c & 0xf];
        }
        return new String(out);
    }

    /**
     * 转图片
     * @param data
     * @param fileName
     * @param type
     */
    public static void saveImage(String data, String fileName, String type){
        BufferedImage image = new BufferedImage(300, 300, BufferedImage.TYPE_BYTE_BINARY);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try{
            ImageIO.write(image, type, byteArrayOutputStream);
            byte[] bytes = hex2byte(data);
            RandomAccessFile file = new RandomAccessFile(fileName.concat(".").concat(type), "rw");
            file.write(bytes);
            file.close();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    /**
     * 反格式化 byte
     * @param s
     * @return
     */
    public static byte[] hex2byte(String s){
        byte[] src = s.toLowerCase().getBytes();
        byte[] ret = new byte[src.length / 2];
        for(int i = 0; i < src.length; i += 2){
            byte hi = src[i];
            byte low = src[i + 1];
            hi = (byte)((hi >= 'a' && hi <= 'f') ? 0x0a + (hi - 'a') : hi - '0');
            low = (byte)((low >= 'a' && low <= 'f') ? 0x0a + (low - 'a') : low - '0');
            ret[i / 2] = (byte)(hi << 4 | low);
        }
        return ret;
    }
    private static byte[] addBytes(byte[] data1, byte[] data2) {
        byte[] data3 = new byte[data1.length + data2.length];
        System.arraycopy(data1, 0, data3, 0, data1.length);
        System.arraycopy(data2, 0, data3, data1.length, data2.length);
        return data3;
    }
    public static String decryptByBase64(String base64, String filePath) {
        if (base64 == null && filePath == null) {
            return "生成文件失败，请给出相应的数据。";
        }
        try {
            Files.write(Paths.get(filePath), Base64.getDecoder().decode(base64),StandardOpenOption.CREATE);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "指定路径下生成文件成功！";
    }

    public static byte[] convertStreamToByte(InputStream is, int lengthOfContent){
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] data = new byte[lengthOfContent];
        int count = -1;
        try {
            while ((count = is.read(data, 0, lengthOfContent)) != -1) {
                outStream.write(data, 0, count);
            }
            data = null;
        }catch (Exception e){
            return null;
        }
        return outStream.toByteArray();
    }

}
